package com.abo.yaas.view.widgets.fields;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import org.vaadin.easyuploads.UploadField;
import org.vaadin.imagefilter.FilterOperation;
import org.vaadin.imagefilter.Image;
import org.vaadin.imagefilter.filters.FitIntoFilter;

import com.abo.yaas.view.DynamicImageResource;
import com.vaadin.Application;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.terminal.StreamResource;
import com.vaadin.terminal.StreamResource.StreamSource;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.ProgressIndicator;
import com.vaadin.ui.Upload;

@SuppressWarnings("serial")
public class UploadImageField extends UploadField {
    
    private final Embedded image = new Embedded();

    private Application app = null;

    private final StreamSource streamSource = new StreamSource() {
        @Override
        public InputStream getStream() {
            final byte[] data = (byte[]) getValue();
            if (data == null) {
                return null;
            }
            return new ByteArrayInputStream(data);
        }
    };

    private UploadImageField() {
        super();
        setSizeFull();
        setMargin(false);
        setFieldType(FieldType.BYTE_ARRAY);
        addComponent(image);
    }

    public UploadImageField(Application app) {
        this();
        this.app = app;
        addStyleName("uploadfield");
    }

    @Override
    public void commit() throws SourceException, InvalidValueException {
        final byte[] data = (byte[]) getValue();
        if (data == null) {
            return;
        }
        final Image image = new Image();
        image.load(data);
        final FilterOperation op = FilterOperation.getByName(FilterOperation.FITINTO);
        final FitIntoFilter fif = (FitIntoFilter) op.getFilter();
        fif.setAllowEnlarging(true);
        fif.setHeight(100);
        fif.setWidth(100);
        image.addOperation(op);
        image.applyOperations();
        final InputStream stream = image.getInputStream();
        try {
            final byte[] bytes = new byte[stream.available()];
            stream.read(bytes);
            setValue(bytes);
            System.out.println("Size is " + bytes.length);
        } catch (final IOException e) {
            e.printStackTrace();
        }
        super.commit();
    }

    @Override
    public void discard() throws SourceException {
        setValue(null);
        super.discard();
    }

    @Override
    protected String getCss(Component c) {
        if (c instanceof Embedded) {
            return "margin-top: 10px;";
        }
        return super.getCss(c);
    }

    @Override
    public void setCaption(String caption) {
        final Iterator<Component> it = getComponentIterator();
        while (it.hasNext()) {
            final Component child = it.next();
            if (child instanceof Upload) {
                ((Upload) child).setButtonCaption(caption);
            }
        }
    }

    @Override
    public void setReadOnly(final boolean readOnly) {
        super.setReadOnly(readOnly);
        final Iterator<Component> it = getComponentIterator();
        while (it.hasNext()) {
            final Component child = it.next();
            if (!(child instanceof ProgressIndicator)) {
                child.setVisible(!readOnly);
            }
        }
    }

    @Override
    protected void updateDisplay() {
        if (getValue() == null) {
            return;
        }
        final String mimeType = getLastMimeType();
        if (mimeType == null || mimeType.equals("image/png")
                || mimeType.equals("image/jpg") || mimeType.equals("image/bmp")
                || mimeType.equals("image/jpeg")
                || mimeType.equals("image/JPEG")
                || mimeType.equals("image/tiff")
                || mimeType.equals("image/BMP")) {
            if (streamSource != null && app != null) {
                final StreamResource resource = new DynamicImageResource(
                        streamSource, app);
                image.setSource(resource);
                image.setWidth("240px");
                image.setWidth("200px");
            }
        }
    }
}
